﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace GameDriver
{
    /// <summary>
    /// Stores a sprite-sheet, current frame, and other relevant data.
    /// Sprite-sheets must contain frames of uniform size, and states with a uniform number of frames.
    /// </summary>
    public class Animation
    {
        private Texture2D spriteSheet;
        private Rectangle sourceRect;
        private int frameWidth, frameHeight;
        private int currentFrame, state;
        private int delay, timePassed;
        private int frameCount { get { return spriteSheet.Width / frameWidth; } }

        /// <summary>
        /// The current frame in the animation.
        /// </summary>
        public int CurrentFrame
        {
            get { return currentFrame; }
            set { currentFrame = value; sourceRect.X = currentFrame * frameWidth; }
        }
        /// <summary>
        /// The current state (y-position on the sprite-sheet) as an integer.
        /// </summary>
        public int State
        {
            get { return state; }
            set { state = value; sourceRect.Y = state * frameHeight; }
        }

        /// <summary>
        /// Create a new animation.
        /// </summary>
        /// <param name="ss">The sprite-sheet to use.</param>
        /// <param name="w">The width of an individual frame.</param>
        /// <param name="h">The height of an individual frame.</param>
        /// <param name="fps">The number of frames per second. (Update speed.)</param>
        public Animation(Texture2D ss, int w, int h, int fps)
        {
            spriteSheet = ss;
            frameWidth = w;
            frameHeight = h;
            sourceRect = new Rectangle(0, 0, w, h);
            currentFrame = 0;
            state = 0;
            delay = 1000 / fps;
            timePassed = 0;
        }

        /// <summary>
        /// Update the animation - should be called once every frame.
        /// </summary>
        /// <param name="gameTime">Used to find the time passed since the last frame.</param>
        public void Update(GameTime gameTime)
        {
            timePassed += gameTime.ElapsedGameTime.Milliseconds;
            if (timePassed > delay)
            {
                CurrentFrame++;
                timePassed -= delay;
                if (currentFrame == frameCount)
                    CurrentFrame = 0;
            }
        }

        /// <summary>
        /// Draw the current frame of the animation to the screen.
        /// </summary>
        /// <param name="spriteBatch">The SpriteBatch to use for rendering.</param>
        /// <param name="dest">The position to render it at.</param>
        public void Draw(SpriteBatch spriteBatch, Vector2 dest)
        {
            Draw(spriteBatch, new Rectangle((int)dest.X, (int)dest.Y, frameWidth, frameHeight));
        }
        /// <summary>
        /// Draw the current frame of the animation to the screen.
        /// </summary>
        /// <param name="spriteBatch">The SpriteBatch to use for rendering.</param>
        /// <param name="dest">The rectangle to render it in.</param>
        public void Draw(SpriteBatch spriteBatch, Rectangle dest)
        {
            spriteBatch.Draw(spriteSheet, dest, sourceRect, Color.White);
        }
    }
}
